package top.igotcha.chapter.chapter3;

/**
 * @author Gotcha
 * @date 2021/2/28
 * @describe 同步模式之保护性暂停
 * - 有一个结果需要从一个线程传递到另一个线程，让他们关联同一个 GuardedObject
 * - 如果有结果不断从一个线程到另一个线程那么可以使用消息队列（见生产者/消费者）
 * - JDK 中，join 的实现、Future 的实现，采用的就是此模式
 * - 因为要等待另一方的结果，因此归类到同步模式
 */
public class GuardedSuspension01 {
    public static void main(String[] args) {
        String hello = "hello thread!";
        Guarded guarded = new Guarded();
        new Thread(()->{
            System.out.println("想要得到结果");
            synchronized (guarded) {
                System.out.println("结果是："+guarded.getResponse());
            }
            System.out.println("得到结果");
        }).start();

        new Thread(()->{
            System.out.println("设置结果");
            synchronized (guarded) {
                guarded.setResponse(hello);
            }
        }).start();
    }
}
class Guarded {
    /**
     * 要返回的结果
     */
    public Object response;

    //优雅地使用wait/notify
    public Object getResponse() {
        //如果返回结果为空就一直等待，避免虚假唤醒
        while(response == null) {
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return response;
    }

    public void setResponse(Object response) {
        this.response = response;
        synchronized (this) {
            //唤醒休眠的线程
            this.notifyAll();
        }
    }
    @Override
    public String toString() {
        return "Guarded{" +
                "response=" + response +
                '}';
    }
}
